package com.quectel.mobile.util;

import com.google.common.base.Preconditions;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.partybuilding.dto.PartyPersonDto;
import com.quectel.mobile.constants.MobileSystemConstants;
import com.quectel.mobile.interceptor.LoginMobileUserSession;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.redis.RedisUtils;
import com.quectel.util.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * session管理器
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2022-07-27 11:26:00
 */
@Slf4j
public class SessionHolder {
    /**
     * 得到session
     *
     * @return
     */
    public static LoginMobileUserSession getLoginMobileUserSession() {

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        Preconditions.checkArgument(requestAttributes != null, "ServletRequestAttributes is null");
        HttpServletRequest httpServletRequest = requestAttributes.getRequest();
        Preconditions.checkArgument(httpServletRequest != null, "HttpServletRequest is null");

        String token = httpServletRequest.getHeader("token");
        log.debug("token --- " + token);
        if (org.apache.commons.lang3.StringUtils.isEmpty(token)) {
            token = httpServletRequest.getParameter("token");
        }
        if (StringUtils.isNotBlank(token)) {
            //header和url都没有传入token
            LoginMobileUserSession session = (LoginMobileUserSession) httpServletRequest.getAttribute(MobileSystemConstants.TOKEN_USER_SESSION);
            if (session != null) {
                return session;
            }
            String sessionStr = RedisUtils.get(MobileSystemConstants.TOKEN_USER_SESSION + token);
            if (StringUtils.isNotBlank(sessionStr)) {
                return JacksonUtils.parse(sessionStr, LoginMobileUserSession.class);
            }
        }
        return null;
    }

    /**
     * 修改session信息
     *
     * @param modifiedSession 被修改过的session
     * @return
     */
    public static LoginMobileUserSession resetLoginMobileUserSession(LoginMobileUserSession modifiedSession) {

        if (modifiedSession.getMobileUser() !=null){
            // 填充下党员信息
            PartyPersonDto partyPersonDto =
                    SpringUtils.getBean(ExportFactory.class).getPartyPersonService().selectOne(modifiedSession.getTenantId(), modifiedSession.getMobileUser().getMobile());
            if (partyPersonDto != null){
                modifiedSession.setPartyPerson(partyPersonDto);
            }
        }

        RedisUtils.set(
                MobileSystemConstants.TOKEN_USER_SESSION + modifiedSession.getToken(),
                JacksonUtils.toJsonString(modifiedSession),
                SystemConstants.LoginType.JS_API.getType().equals(modifiedSession.getLoginType())
                        ? MobileSystemConstants.JSAPI_EXPIRE_TIME : MobileSystemConstants.APP_EXPIRE_TIME,
                TimeUnit.SECONDS
        );
        if (modifiedSession.getMobileUser() != null) {
            modifiedSession.getMobileUser().setPassword(null);

            //双向绑定
            RedisUtils.hSet(
                    MobileSystemConstants.USER_TOKEN_SESSION + modifiedSession.getMobileUser().getId(),
                    modifiedSession.getToken(),
                    SystemConstants.EMPTY_STR,
                    SystemConstants.LoginType.JS_API.getType().equals(modifiedSession.getLoginType())
                            ? MobileSystemConstants.JSAPI_EXPIRE_TIME : MobileSystemConstants.APP_EXPIRE_TIME,
                    TimeUnit.SECONDS
            );

        }
        //不返回前端
        modifiedSession.setOfficialAccountsType(null);
        modifiedSession.setAppId(null);
        modifiedSession.setOpenId(null);
        return modifiedSession;
    }

    /**
     * 删除用户的token
     *
     * @param id
     */
    public static void removeUserToken(Long id) {
        //需要踢出已经授权的token
        Map<String, String> tokens = RedisUtils.hGetAll(MobileSystemConstants.USER_TOKEN_SESSION + id);
        if (tokens != null) {
            tokens.forEach((k, v) -> RedisUtils.del(MobileSystemConstants.USER_TOKEN_SESSION + k));
        }
        RedisUtils.del(MobileSystemConstants.USER_TOKEN_SESSION + id);
    }

    /**
     * 退出当前session
     */
    public static void logout() {
        LoginMobileUserSession session = getLoginMobileUserSession();
        //删除token绑定人员
        RedisUtils.del(MobileSystemConstants.TOKEN_USER_SESSION + session.getToken());
        //删除人员所绑定的当前token
        RedisUtils.hDel(MobileSystemConstants.USER_TOKEN_SESSION + session.getMobileUser().getId(), session.getToken());
    }

    public static void checkMobileUser() {
        LoginMobileUserSession loginMobileUserSession = getLoginMobileUserSession();
        Preconditions.checkNotNull(loginMobileUserSession);
    }

    public static void checkHousehold() {
        LoginMobileUserSession loginMobileUserSession = getLoginMobileUserSession();
        Preconditions.checkNotNull(loginMobileUserSession.getCurrentHousehold());
    }

    public static void checkPartyPerson() {
        LoginMobileUserSession loginMobileUserSession = getLoginMobileUserSession();
        Preconditions.checkNotNull(loginMobileUserSession.getPartyPerson());
    }
}
